`timescale 1ps / 1ps
module ctrl(
    input [31:0] ins,
    output [4:0] Rs,Rt,Rd,
    output [15:0] imm16,
    output reg [2:0] ALUctr,
    output reg Branch,
    output reg Jump,
    output reg RegWr,
    output reg RegDst,
    output reg ExtOp,
    output reg ALUsrc,
    output reg MemWr,
    output reg MemtoReg
);
reg [5:0] OP;
reg [5:0] func;
assign Rs = ins[25:21];
assign Rt = ins[20:16];
assign Rd = ins[15:11];
assign imm16 = ins[15:0];

parameter R = 6'b000000, LW = 6'b100011, SW = 6'b101011, BEQ = 6'b000100, J = 6'b000010;
parameter ADDI = 6'b001000;
parameter ADD = 6'b100000, SUB = 6'b100010, SLT = 6'b101010, AND = 6'b100100 , OR = 6'b100101;
parameter SLTU = 6'b101011;

always @(*) begin
    OP = ins[31:26];
    func = ins[5:0];
    case (OP)
        R:begin
            Branch = 0;
			Jump = 0;
			RegDst = 1;
			ALUsrc = 0;	
			MemtoReg = 0;
			RegWr = 1;
			MemWr = 0;
			ExtOp = 0;
            case (func)
                ADD:  ALUctr = 0;
                SUB:  ALUctr = 2;
                AND:  ALUctr = 4;
                OR :  ALUctr = 5; 
                SLT:  ALUctr = 6;
                SLTU: ALUctr = 7;
            endcase
        end

        LW:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 0;
            MemtoReg = 1;

            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 0;
        end

        SW:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 0; 
        end

        ADDI:begin
            Branch = 0;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 1;
            
            MemWr = 1;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 1; 
            ALUctr = 0;
        end
        BEQ:begin
            Branch = 1;
            Jump = 0;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 2;
        end
        J:begin
            Branch = 0;
            Jump = 1;
            
            RegDst = 0;
            RegWr = 0;
            
            MemWr = 0;
            MemtoReg = 0;
            
            ExtOp = 1;
            ALUsrc = 0; 
            ALUctr = 0;
        end
    endcase 


end

endmodule
